/* This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 *
 * http://www.gnu.org/copyleft/gpl.html
 */

package l1j.jrwz.server.clientpackets;

import static l1j.jrwz.server.model.skill.L1SkillId.COOKING_1_0_N;
import static l1j.jrwz.server.model.skill.L1SkillId.COOKING_1_0_S;
import static l1j.jrwz.server.model.skill.L1SkillId.COOKING_1_6_N;
import static l1j.jrwz.server.model.skill.L1SkillId.COOKING_1_6_S;
import static l1j.jrwz.server.model.skill.L1SkillId.COOKING_2_0_N;
import static l1j.jrwz.server.model.skill.L1SkillId.COOKING_2_0_S;
import static l1j.jrwz.server.model.skill.L1SkillId.COOKING_2_6_N;
import static l1j.jrwz.server.model.skill.L1SkillId.COOKING_2_6_S;
import static l1j.jrwz.server.model.skill.L1SkillId.COOKING_3_0_N;
import static l1j.jrwz.server.model.skill.L1SkillId.COOKING_3_0_S;
import static l1j.jrwz.server.model.skill.L1SkillId.COOKING_3_6_N;
import static l1j.jrwz.server.model.skill.L1SkillId.COOKING_3_6_S;
import static l1j.jrwz.server.model.skill.L1SkillId.SHAPE_CHANGE;
import static l1j.jrwz.server.model.skill.L1SkillId.STATUS_BLUE_POTION;
import static l1j.jrwz.server.model.skill.L1SkillId.STATUS_BRAVE;
import static l1j.jrwz.server.model.skill.L1SkillId.STATUS_CHAT_PROHIBITED;
import static l1j.jrwz.server.model.skill.L1SkillId.STATUS_ELFBRAVE;
import static l1j.jrwz.server.model.skill.L1SkillId.STATUS_HASTE;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

import l1j.jrwz.Config;
import l1j.jrwz.L1DatabaseFactory;
import l1j.jrwz.server.ActionCodes;
import l1j.jrwz.server.ClientThread;
import l1j.jrwz.server.WarTimeController;
import l1j.jrwz.server.datatables.CharacterTable;
import l1j.jrwz.server.datatables.GetBackRestartTable;
import l1j.jrwz.server.datatables.SkillsTable;
import l1j.jrwz.server.model.Getback;
import l1j.jrwz.server.model.L1CastleLocation;
import l1j.jrwz.server.model.L1Clan;
import l1j.jrwz.server.model.L1Cooking;
import l1j.jrwz.server.model.L1PolyMorph;
import l1j.jrwz.server.model.L1War;
import l1j.jrwz.server.model.L1World;
import l1j.jrwz.server.model.Instance.L1PcInstance;
import l1j.jrwz.server.model.Instance.L1SummonInstance;
import l1j.jrwz.server.model.skill.L1SkillUse;
import l1j.jrwz.server.serverpackets.S_ActiveSpells;
import l1j.jrwz.server.serverpackets.S_AddSkill;
import l1j.jrwz.server.serverpackets.S_Bookmarks;
import l1j.jrwz.server.serverpackets.S_CharTitle;
import l1j.jrwz.server.serverpackets.S_CharacterConfig;
import l1j.jrwz.server.serverpackets.S_InitialAbilityGrowth;
import l1j.jrwz.server.serverpackets.S_InvList;
import l1j.jrwz.server.serverpackets.S_Karma;
import l1j.jrwz.server.serverpackets.S_MapID;
import l1j.jrwz.server.serverpackets.S_OwnCharPack;
import l1j.jrwz.server.serverpackets.S_OwnCharStatus;
import l1j.jrwz.server.serverpackets.S_SPMR;
import l1j.jrwz.server.serverpackets.S_ServerMessage;
import l1j.jrwz.server.serverpackets.S_SkillBrave;
import l1j.jrwz.server.serverpackets.S_SkillHaste;
import l1j.jrwz.server.serverpackets.S_SkillIconGFX;
import l1j.jrwz.server.serverpackets.S_SummonPack;
import l1j.jrwz.server.serverpackets.S_Unknown1;
import l1j.jrwz.server.serverpackets.S_Unknown2;
import l1j.jrwz.server.serverpackets.S_War;
import l1j.jrwz.server.serverpackets.S_Weather;
import l1j.jrwz.server.serverpackets.S_bonusstats;
import l1j.jrwz.server.templates.L1BookMark;
import l1j.jrwz.server.templates.L1GetBackRestart;
import l1j.jrwz.server.templates.L1Skills;
import l1j.jrwz.server.utils.SQLUtil;

// Referenced classes of package l1j.jrwz.server.clientpackets:
// ClientBasePacket
//

/**
 * 處理收到由客戶端傳來登入到伺服器的封包
 */
public class C_LoginToServer extends ClientBasePacket {

    private static final String C_LOGIN_TO_SERVER = "[C] C_LoginToServer";
    private static Logger _log = Logger.getLogger(C_LoginToServer.class
            .getName());

    @Override
    public void execute(byte[] decrypt, ClientThread client) {
        try {
            read(decrypt);
            if (client == null) {
                return;
            }
            if (client.getActiveChar() != null) {
                _log.info("同一个角色重复登陆，强制切断 " + client.getHostname() + ") 的连接。");
                client.close();
                return;
            }
            String charName = readS();
            L1PcInstance pc = L1PcInstance.load(charName);
            if (pc == null) {
                return;
            }

            String login = client.getAccountName();
            if (!login.equals(pc.getAccountName())) {
                _log.info("无效的角色名称: char=" + charName + " account=" + login
                        + " host=" + client.getHostname());
                client.close();
                return;
            }

            if (Config.LEVEL_DOWN_RANGE != 0) {
                if (pc.getHighLevel() - pc.getLevel() >= Config.LEVEL_DOWN_RANGE) {
                    _log.info("登陆请求超出了容忍的 等级下降的角色: char=" + charName
                            + " account=" + login + " host="
                            + client.getHostname());
                    client.kick();
                    return;
                }
            }

            _log.info("角色进入游戏: char=" + charName + " account=" + login
                    + " host=" + client.getHostname());

            int currentHpAtLoad = pc.getCurrentHp();
            int currentMpAtLoad = pc.getCurrentMp();
            pc.clearSkillMastery();
            pc.setOnlineStatus(1);
            CharacterTable.updateOnlineStatus(pc);
            L1World.getInstance().storeObject(pc);

            pc.setNetConnection(client);
            pc.setPacketOutput(client);
            client.setActiveChar(pc);

            S_Unknown1 s_unknown1 = new S_Unknown1();
            pc.sendPackets(s_unknown1);
            S_Unknown2 s_unknown2 = new S_Unknown2();
            pc.sendPackets(s_unknown2);
            S_InitialAbilityGrowth s_initialAbility = new S_InitialAbilityGrowth(
                    pc);
            pc.sendPackets(s_initialAbility); // 初始能力加成
            bookmarks(pc);

            // 如果設定檔中設定自動回村的話
            GetBackRestartTable gbrTable = GetBackRestartTable.getInstance();
            L1GetBackRestart[] gbrList = gbrTable.getGetBackRestartTableList();
            for (L1GetBackRestart gbr : gbrList) {
                if (pc.getMapId() == gbr.getArea()) {
                    pc.setX(gbr.getLocX());
                    pc.setY(gbr.getLocY());
                    pc.setMap(gbr.getMapId());
                    break;
                }
            }

            // altsettings.properties 中 GetBack 設定為 true 就自動回村
            if (Config.GET_BACK) {
                int[] loc = Getback.GetBack_Location(pc, true);
                pc.setX(loc[0]);
                pc.setY(loc[1]);
                pc.setMap((short) loc[2]);
            }

            // 如果標記是在戰爭期間，如果不是血盟成員回到城堡。
            int castle_id = L1CastleLocation.getCastleIdByArea(pc);
            if (0 < castle_id) {
                if (WarTimeController.getInstance().isNowWar(castle_id)) {
                    L1Clan clan = L1World.getInstance().getClan(
                            pc.getClanname());
                    if (clan != null) {
                        if (clan.getCastleId() != castle_id) {
                            // 沒有城堡
                            int[] loc = new int[3];
                            loc = L1CastleLocation.getGetBackLoc(castle_id);
                            pc.setX(loc[0]);
                            pc.setY(loc[1]);
                            pc.setMap((short) loc[2]);
                        }
                    } else {
                        // 有城堡就回到城堡
                        int[] loc = new int[3];
                        loc = L1CastleLocation.getGetBackLoc(castle_id);
                        pc.setX(loc[0]);
                        pc.setY(loc[1]);
                        pc.setMap((short) loc[2]);
                    }
                }
            }

            L1World.getInstance().addVisibleObject(pc);
            S_ActiveSpells s_activespells = new S_ActiveSpells(pc);
            pc.sendPackets(s_activespells);

            pc.beginGameTimeCarrier();

            S_OwnCharStatus s_owncharstatus = new S_OwnCharStatus(pc);
            pc.sendPackets(s_owncharstatus);

            S_MapID s_mapid = new S_MapID(pc.getMapId(), pc.getMap()
                    .isUnderwater());
            pc.sendPackets(s_mapid);

            S_OwnCharPack s_owncharpack = new S_OwnCharPack(pc);
            pc.sendPackets(s_owncharpack);

            pc.sendPackets(new S_SPMR(pc));

            // XXX S_OwnCharPack 可能是不必要的
            S_CharTitle s_charTitle = new S_CharTitle(pc.getId(), pc.getTitle());
            pc.sendPackets(s_charTitle);
            pc.broadcastPacket(s_charTitle);

            pc.sendVisualEffectAtLogin(); // 皇冠，毒，水和其他視覺效果顯示
            pc.sendPackets(new S_Karma(pc)); // 友好度
            pc.sendPackets(new S_Weather(L1World.getInstance().getWeather()));

            items(pc);
            skills(pc);
            buff(client, pc);
            pc.turnOnOffLight();

            if (pc.getCurrentHp() > 0) {
                pc.setDead(false);
                pc.setStatus(0);
            } else {
                pc.setDead(true);
                pc.setStatus(ActionCodes.ACTION_Die);
            }

            if (pc.getLevel() >= 51 && pc.getLevel() - 50 > pc.getBonusStats()) {
                if ((pc.getBaseStr() + pc.getBaseDex() + pc.getBaseCon()
                        + pc.getBaseInt() + pc.getBaseWis() + pc.getBaseCha()) < 210) {
                    pc.sendPackets(new S_bonusstats(pc.getId(), 1));
                }
            }

            if (Config.CHARACTER_CONFIG_IN_SERVER_SIDE) {
                pc.sendPackets(new S_CharacterConfig(pc.getId()));
            }

            serchSummon(pc);

            WarTimeController.getInstance().checkCastleWar(pc);

            if (pc.getClanid() != 0) { // 有血盟
                L1Clan clan = L1World.getInstance().getClan(pc.getClanname());
                if (clan != null) {
                    if (pc.getClanid() == clan.getClanId() && // 血盟解散、又重新用同樣名字創立時的對策
                            pc.getClanname().toLowerCase()
                                    .equals(clan.getClanName().toLowerCase())) {
                        L1PcInstance[] clanMembers = clan.getOnlineClanMember();
                        for (L1PcInstance clanMember : clanMembers) {
                            if (clanMember.getId() != pc.getId()) {
                                clanMember.sendPackets(new S_ServerMessage(843,
                                        pc.getName())); // 只今、血盟員の%0%sがゲームに接続しました。
                            }
                        }

                        // 取得所有的盟戰
                        for (L1War war : L1World.getInstance().getWarList()) {
                            boolean ret = war.CheckClanInWar(pc.getClanname());
                            if (ret) { // 盟戰中
                                String enemy_clan_name = war
                                        .GetEnemyClanName(pc.getClanname());
                                if (enemy_clan_name != null) {
                                    // あなたの血盟が現在_血盟と交戦中です。
                                    pc.sendPackets(new S_War(8, pc
                                            .getClanname(), enemy_clan_name));
                                }
                                break;
                            }
                        }
                    } else {
                        pc.setClanid(0);
                        pc.setClanname("");
                        pc.setClanRank(0);
                        pc.save(); // 儲存玩家的資料到資料庫中
                    }
                }
            }

            if (pc.getPartnerId() != 0) { // 結婚中
                L1PcInstance partner = (L1PcInstance) L1World.getInstance()
                        .findObject(pc.getPartnerId());
                if (partner != null && partner.getPartnerId() != 0) {
                    if (pc.getPartnerId() == partner.getId()
                            && partner.getPartnerId() == pc.getId()) {
                        pc.sendPackets(new S_ServerMessage(548)); // 你的情人目前正在线上。
                        partner.sendPackets(new S_ServerMessage(549)); // 你的情人上线了!!
                    }
                }
            }

            if (currentHpAtLoad > pc.getCurrentHp()) {
                pc.setCurrentHp(currentHpAtLoad);
            }
            if (currentMpAtLoad > pc.getCurrentMp()) {
                pc.setCurrentMp(currentMpAtLoad);
            }
            pc.startHpRegeneration();
            pc.startMpRegeneration();
            pc.startObjectAutoUpdate();
            client.CharReStart(false);
            pc.beginExpMonitor();
            pc.save(); // 儲存玩家的資料到資料庫中

            pc.sendPackets(new S_OwnCharStatus(pc));

            if (pc.getHellTime() > 0) {
                pc.beginHell(false);
            }
        } catch (final Exception e) {
            _log.log(Level.SEVERE, e.getLocalizedMessage(), e);
        } finally {
            finish();
        }
    }

    private void bookmarks(L1PcInstance pc) {

        Connection con = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {

            con = L1DatabaseFactory.getInstance().getConnection();
            pstm = con
                    .prepareStatement("SELECT * FROM character_teleport WHERE char_id=? ORDER BY name ASC");
            pstm.setInt(1, pc.getId());

            rs = pstm.executeQuery();
            while (rs.next()) {
                L1BookMark bookmark = new L1BookMark();
                bookmark.setId(rs.getInt("id"));
                bookmark.setCharId(rs.getInt("char_id"));
                bookmark.setName(rs.getString("name"));
                bookmark.setLocX(rs.getInt("locx"));
                bookmark.setLocY(rs.getInt("locy"));
                bookmark.setMapId(rs.getShort("mapid"));
                S_Bookmarks s_bookmarks = new S_Bookmarks(bookmark.getName(),
                        bookmark.getMapId(), bookmark.getId());
                pc.addBookMark(bookmark);
                pc.sendPackets(s_bookmarks);
            }
        } catch (SQLException e) {
            _log.log(Level.SEVERE, e.getLocalizedMessage(), e);
        } finally {
            SQLUtil.close(rs);
            SQLUtil.close(pstm);
            SQLUtil.close(con);
        }
    }

    private void buff(ClientThread clientthread, L1PcInstance pc) {
        Connection con = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {

            con = L1DatabaseFactory.getInstance().getConnection();
            pstm = con
                    .prepareStatement("SELECT * FROM character_buff WHERE char_obj_id=?");
            pstm.setInt(1, pc.getId());
            rs = pstm.executeQuery();
            while (rs.next()) {
                int skillid = rs.getInt("skill_id");
                int remaining_time = rs.getInt("remaining_time");
                if (skillid == SHAPE_CHANGE) { // 變身
                    int poly_id = rs.getInt("poly_id");
                    L1PolyMorph.doPoly(pc, poly_id, remaining_time,
                            L1PolyMorph.MORPH_BY_LOGIN);
                } else if (skillid == STATUS_BRAVE) { // 勇敢藥水
                    pc.sendPackets(new S_SkillBrave(pc.getId(), 1,
                            remaining_time));
                    pc.broadcastPacket(new S_SkillBrave(pc.getId(), 1, 0));
                    pc.setBraveSpeed(1);
                    pc.setSkillEffect(skillid, remaining_time * 1000);
                } else if (skillid == STATUS_ELFBRAVE) { // 精靈餅乾
                    pc.sendPackets(new S_SkillBrave(pc.getId(), 3,
                            remaining_time));
                    pc.broadcastPacket(new S_SkillBrave(pc.getId(), 3, 0));
                    pc.setBraveSpeed(1);
                    pc.setSkillEffect(skillid, remaining_time * 1000);
                } else if (skillid == STATUS_HASTE) { // 加速
                    pc.sendPackets(new S_SkillHaste(pc.getId(), 1,
                            remaining_time));
                    pc.broadcastPacket(new S_SkillHaste(pc.getId(), 1, 0));
                    pc.setMoveSpeed(1);
                    pc.setSkillEffect(skillid, remaining_time * 1000);
                } else if (skillid == STATUS_BLUE_POTION) { // 藍色藥水
                    pc.sendPackets(new S_SkillIconGFX(34, remaining_time));
                    pc.setSkillEffect(skillid, remaining_time * 1000);
                } else if (skillid == STATUS_CHAT_PROHIBITED) { // 禁言
                    pc.sendPackets(new S_SkillIconGFX(36, remaining_time));
                    pc.setSkillEffect(skillid, remaining_time * 1000);
                } else if (skillid >= COOKING_1_0_N && skillid <= COOKING_1_6_N
                        || skillid >= COOKING_1_0_S && skillid <= COOKING_1_6_S
                        || skillid >= COOKING_2_0_N && skillid <= COOKING_2_6_N
                        || skillid >= COOKING_2_0_S && skillid <= COOKING_2_6_S
                        || skillid >= COOKING_3_0_N && skillid <= COOKING_3_6_N
                        || skillid >= COOKING_3_0_S && skillid <= COOKING_3_6_S) { // 料理
                    L1Cooking.eatCooking(pc, skillid, remaining_time);
                } else {
                    L1SkillUse l1skilluse = new L1SkillUse();
                    l1skilluse.handleCommands(clientthread.getActiveChar(),
                            skillid, pc.getId(), pc.getX(), pc.getY(), null,
                            remaining_time, L1SkillUse.TYPE_LOGIN);
                }
            }
        } catch (SQLException e) {
            _log.log(Level.SEVERE, e.getLocalizedMessage(), e);
        } finally {
            SQLUtil.close(rs);
            SQLUtil.close(pstm);
            SQLUtil.close(con);
        }
    }

    @Override
    public String getType() {
        return C_LOGIN_TO_SERVER;
    }

    private void items(L1PcInstance pc) {
        // 從資料庫中讀取角色的道具
        CharacterTable.getInstance().restoreInventory(pc);

        pc.sendPackets(new S_InvList(pc.getInventory().getItems()));
    }

    private void serchSummon(L1PcInstance pc) {
        for (L1SummonInstance summon : L1World.getInstance().getAllSummons()) {
            if (summon.getMaster().getId() == pc.getId()) {
                summon.setMaster(pc);
                pc.addPet(summon);
                for (L1PcInstance visiblePc : L1World.getInstance()
                        .getVisiblePlayer(summon)) {
                    visiblePc.sendPackets(new S_SummonPack(summon, visiblePc));
                }
            }
        }
    }

    private void skills(L1PcInstance pc) {
        Connection con = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {

            con = L1DatabaseFactory.getInstance().getConnection();
            pstm = con
                    .prepareStatement("SELECT * FROM character_skills WHERE char_obj_id=?");
            pstm.setInt(1, pc.getId());
            rs = pstm.executeQuery();
            int i = 0;
            int lv1 = 0;
            int lv2 = 0;
            int lv3 = 0;
            int lv4 = 0;
            int lv5 = 0;
            int lv6 = 0;
            int lv7 = 0;
            int lv8 = 0;
            int lv9 = 0;
            int lv10 = 0;
            int lv11 = 0;
            int lv12 = 0;
            int lv13 = 0;
            int lv14 = 0;
            int lv15 = 0;
            int lv16 = 0;
            int lv17 = 0;
            int lv18 = 0;
            int lv19 = 0;
            int lv20 = 0;
            int lv21 = 0;
            int lv22 = 0;
            int lv23 = 0;
            int lv24 = 0;
            int lv25 = 0;
            int lv26 = 0;
            int lv27 = 0;
            int lv28 = 0;
            while (rs.next()) {
                int skillId = rs.getInt("skill_id");
                L1Skills l1skills = SkillsTable.getInstance().getTemplate(
                        skillId);
                if (l1skills.getSkillLevel() == 1) {
                    lv1 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 2) {
                    lv2 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 3) {
                    lv3 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 4) {
                    lv4 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 5) {
                    lv5 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 6) {
                    lv6 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 7) {
                    lv7 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 8) {
                    lv8 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 9) {
                    lv9 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 10) {
                    lv10 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 11) {
                    lv11 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 12) {
                    lv12 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 13) {
                    lv13 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 14) {
                    lv14 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 15) {
                    lv15 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 16) {
                    lv16 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 17) {
                    lv17 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 18) {
                    lv18 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 19) {
                    lv19 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 20) {
                    lv20 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 21) {
                    lv21 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 22) {
                    lv22 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 23) {
                    lv23 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 24) {
                    lv24 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 25) {
                    lv25 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 26) {
                    lv26 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 27) {
                    lv27 |= l1skills.getId();
                }
                if (l1skills.getSkillLevel() == 28) {
                    lv28 |= l1skills.getId();
                }
                i = lv1 + lv2 + lv3 + lv4 + lv5 + lv6 + lv7 + lv8 + lv9 + lv10
                        + lv11 + lv12 + lv13 + lv14 + lv15 + lv16 + lv17 + lv18
                        + lv19 + lv20 + lv21 + lv22 + lv23 + lv24 + lv25 + lv26
                        + lv27 + lv28;
                pc.setSkillMastery(skillId);
            }
            if (i > 0) {
                pc.sendPackets(new S_AddSkill(lv1, lv2, lv3, lv4, lv5, lv6,
                        lv7, lv8, lv9, lv10, lv11, lv12, lv13, lv14, lv15,
                        lv16, lv17, lv18, lv19, lv20, lv21, lv22, lv23, lv24,
                        lv25, lv26, lv27, lv28));
                // _log.warning("ここたち来るのね＠直訳");
            }
        } catch (SQLException e) {
            _log.log(Level.SEVERE, e.getLocalizedMessage(), e);
        } finally {
            SQLUtil.close(rs);
            SQLUtil.close(pstm);
            SQLUtil.close(con);
        }
    }
}
